//
// Created by postgres on 4/17/17.
//
#include "stdio.h"
#include "stdlib.h"
#include "../include/02_linear_list/LinkList.h"
#include "../include/common/memutils.h"

Status InitLinkList(LinkList *l){
    *l=(LinkList)palloc(sizeof(Node));
    if(*l==NULL)return ERROR;
    else{
        (*l)->next=NULL;
        return OK;
    }
}
Status LinkListEmpty(LinkList l){
    if(l->next)return TRUE;
    else return FALSE;
}
/* 初始条件：顺序线性表L已存在。操作结果：返回L中数据元素个数 */
int LinkListLength(LinkList L)
{
    int i=0;
    LinkList p=L->next; /* p指向第一个结点 */
    while(p)
    {
        i++;
        p=p->next;
    }
    return i;
}
// add a element on tail
Status addNode(LinkList *L,ElemType e){
    LinkList p,li;
    p=*L;
    while(p->next){
        p=p->next;
    }
    li=(LinkList)palloc(sizeof(Node));
    /* 存储分配失败 */
    if(li==NULL)return ERROR;
    li->data=e;
    li->next=NULL;
    p->next=li;
    return OK;
}
Status LinkListInsert(LinkList *L,int i,ElemType e){
    int j=1,len=0;
    len=LinkListLength(*L)+1;
    if(i<1||i>len) {
        fprintf(stderr, "%s\n", "offset of List boundary");
        return FALSE;
    }
    LinkList p,li;
    p=*L;
    while(p->next&&j<i){
        p=p->next;
        j++;
    }
    li=(LinkList)palloc(sizeof(Node));
    /* 存储分配失败 */
    if(li==NULL)return ERROR;
    li->data=e;
    li->next=p->next;
    p->next=li;
    return OK;

}
Status LinkListDelete(LinkList *L,int i,ElemType *e){
    int j=1,len=0;
    len=LinkListLength(*L);
    if(i<1||i>len) {
        fprintf(stderr, "%s\n", "offset of List boundary");
        return FALSE;
    }
    LinkList p,pi;
    p=*L;
    while(p->next&&j<i){
        p=p->next;
        j++;
    }
    pi=p->next;
    p->next=pi->next;
    *e=pi->data;
    pfree(pi);
    return OK;
}
Status GetElemLink(LinkList *L,int i,ElemType *e){
    int j=1,len=0;
    len=LinkListLength(*L);
    if(i<1||i>len) {
        fprintf(stderr, "%s\n", "offset of List boundary");
        return FALSE;
    }
    LinkList p;
    p=*L;
    while(p->next&&j<=i){
        p=p->next;
        j++;
    }
    *e=p->data;
    return OK;
}
Status destroyLinkList(LinkList *L){
    LinkList p,q;
    p=*L;
    while(p){
        q=p;
        p=p->next;
        pfree(q);
    }
}
Status LinkList_test(){
    LinkList li;
    int i=8192,e;
    InitLinkList(&li);
    //LinkListDelete(&li,1,&e);
    addNode(&li,8190);
    LinkListInsert(&li,1,8189);
    addNode(&li,8191);
    addNode(&li,8192);
    GetElemLink(&li,3,&e);
    addNode(&li,8193);
    destroyLinkList(&li);


}
